﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Text.Json;

using Microsoft.VisualStudio.TestTools.UnitTesting;

using zijian666.Converts;
using zijian666.Converts.Core;
using zijian666.Converts.Json;

namespace UnitTest
{
    [TestClass]
    public class UnitTest4
    {
        [TestInitialize]
        public void Before()
        {
            if (!Debugger.IsAttached)
            {
            }
            _ = DiagnosticListener.AllListeners.Subscribe(new DiagnosticObserver());
        }

        [TestMethod]
        public void FormatterConverter()
        {
            var converter = Converts.GetFormatterConverter();
            var result = converter.ToInt32("123");
            Assert.AreEqual(123, result);
        }

        [TestMethod]
        public void JsonConvertor()
        {
            Converts.Settings.Protocol = "json";
            Converts.SetStringSerializer(new JsonStringSerializer());

            {
                var data = new
                {
                    id = 1,
                    name = "zijian666",
                };
                var json = data.To<string>();
                Console.WriteLine(json);
                Assert.AreEqual(JsonSerializer.Serialize(data), json);

                var result = json.Convert(data.GetType());
                Assert.IsTrue(result.Success);
                dynamic data2 = result.Value;
                Assert.IsTrue(data.id == (int)data2.id);
                Assert.IsTrue(data.name == (string)data2.name);
            }

            {
                var data = new[]
                {
                    new {id = 1, name = "zijian666"},
                    new {id = 2, name = "blqw"}
                };
                var json = data.To<string>();
                Console.WriteLine(json);
                Assert.AreEqual(JsonSerializer.Serialize(data), json);

                var result = json.Convert(data.GetType());
                Assert.IsTrue(result.Success);
                dynamic data2 = result.Value;
                Assert.AreEqual(data[0].id, data2[0].id);
                Assert.AreEqual(data[0].name, data2[0].name);
                Assert.AreEqual(data[1].id, data2[1].id);
                Assert.AreEqual(data[1].name, data2[1].name);
            }

            {
                var data = new Dictionary<string, dynamic>
                {
                    ["1"] = new { id = 1, name = "zijian666" },
                    ["2"] = new { id = 2, name = "blqw" }
                };
                var json = data.To<string>();
                Console.WriteLine(json);
                Assert.AreEqual(JsonSerializer.Serialize(data), json);

                var type = typeof(Dictionary<,>).MakeGenericType(typeof(string), ((object)data["1"]).GetType());
                var result = json.Convert(type);
                Assert.IsTrue(result.Success);
                dynamic data2 = result.Value;
                Assert.AreEqual(data["1"].id, data2["1"].id);
                Assert.AreEqual(data["1"].name, data2["1"].name);
                Assert.AreEqual(data["2"].id, data2["2"].id);
                Assert.AreEqual(data["2"].name, data2["2"].name);
            }

            {
                var data = new List<dynamic>
                {
                    new {id = 1, name = "zijian666"},
                    new {id = 2, name = "blqw"}
                };
                var json = data.To<string>();
                Console.WriteLine(json);
                Assert.AreEqual(JsonSerializer.Serialize(data), json);

                var type = typeof(List<>).MakeGenericType(((object)data[0]).GetType());
                var result = json.Convert(type);
                Assert.IsTrue(result.Success);
                dynamic data2 = result.Value;
                Assert.AreEqual(data[0].id, data2[0].id);
                Assert.AreEqual(data[0].name, data2[0].name);
                Assert.AreEqual(data[1].id, data2[1].id);
                Assert.AreEqual(data[1].name, data2[1].name);
            }

            {
                var data = new Dictionary<string, dynamic>
                {
                    ["1"] = new { id = 1, name = "zijian666" },
                    ["2"] = new { id = 2, name = "blqw" }
                };
                var json = data.To<string>();
                Console.WriteLine(json);
                Assert.AreEqual(JsonSerializer.Serialize(data), json);

                var result = json.Convert<NameValueCollection>();
                Assert.IsTrue(result.Success);
                var data2 = result.Value;

                Assert.AreEqual(JsonSerializer.Serialize(data["1"]), data2["1"]);
                Assert.AreEqual(JsonSerializer.Serialize(data["2"]), data2["2"]);
            }
        }

        [TestMethod]
        public void JsonToDatetimeBug()
        {
            Converts.Settings.Protocol = "json";
            Converts.SetStringSerializer(new JsonStringSerializer());

            {
                var data = new
                {
                    time = DateTime.Parse("2020-10-06 01:07:27")
                };

                var json = data.To<string>();
                Console.WriteLine(json);
                Assert.AreEqual("{\"time\":\"2020-10-06 01:07:27\"}", json);
            }

            {
                var data = new
                {
                    time = DateTime.Parse("2020-10-06 01:07:27")
                };

                var json = data.Convert<string>(new ConvertSettings().SetToStringArgument(typeof(DateTime), "yyyy年MM月dd日")).Value;
                Console.WriteLine(json);
                Assert.AreEqual("{\"time\":\"2020年10月06日\"}", json);
            }
        }

        [TestMethod]
        public void JsonBug20201006()
        {
            var json = "{\"ID\":1,\"NUMBER\":1,\"NAME\":\"\u4EFB\u660A\u777F\",\"PHONE_BA\":\"13588890280\",\"PHONE_MA\":\"13588828151\",\"GENDER\":\"\u7537\",\"IDENTITY_CARD\":\"33010420121008271X\",\"ADDRESS\":\"\",\"LEAVED\":0,\"CREATED_AT\":\"2019-09-22 05:19:20\",\"MODIFIED_AT\":\"2019-09-22 05:19:20\",\"PHONE\":\"\"}";

            var x = json.To<Students>();
            Console.WriteLine($"{x}");

            var y = x.To("");
            Assert.AreEqual(json, y);
        }

        public class Students
        {
            public int ID { get; set; }
            public int NUMBER { get; set; }
            public string NAME { get; set; }
            public string PHONE_BA { get; set; }
            public string PHONE_MA { get; set; }
            public string GENDER { get; set; }
            public string IDENTITY_CARD { get; set; }
            public string ADDRESS { get; set; }
            public int LEAVED { get; set; }
            public DateTime CREATED_AT { get; set; }
            public DateTime MODIFIED_AT { get; set; }
            public string PHONE { get; set; }
        }
    }
}
